import { localStore, LocalStore } from './localStore.js';
import { sessStore, SessionStore } from './sessStore.js';
import { memStore, MemoryStore } from './memStore.js';
import { indexedStore, IndexedStore } from './indexedStore.js';
import { BaseStore } from './BaseStore.js';

/**
 * 存储类型枚举
 */
export const STORAGE_TYPES = {
  INDEXED: 'indexed',    // IndexedDB - 主要存储
  LOCAL: 'local',        // localStorage - 备用存储
  SESSION: 'session',    // sessionStorage - 会话存储
  MEMORY: 'memory'       // 内存存储 - 临时存储
};

/**
 * 统一存储管理器
 * 以 IndexedDB 为主要存储，其他存储类型作为备用或特定用途
 */
class StoreManager {
  constructor() {
    this.stores = {
      [STORAGE_TYPES.INDEXED]: indexedStore,
      [STORAGE_TYPES.LOCAL]: localStore,
      [STORAGE_TYPES.SESSION]: sessStore,
      [STORAGE_TYPES.MEMORY]: memStore
    };
    this.defaultType = STORAGE_TYPES.INDEXED; // 默认使用 IndexedDB
    this.fallbackType = STORAGE_TYPES.LOCAL;  // 备用存储类型
    this.isIndexedDBAvailable = null;
  }

  /**
   * 检查 IndexedDB 是否可用
   * @returns {Promise<boolean>}
   */
  async checkIndexedDBAvailability() {
    if (this.isIndexedDBAvailable !== null) {
      return this.isIndexedDBAvailable;
    }

    try {
      if (!window.indexedDB) {
        this.isIndexedDBAvailable = false;
        return false;
      }

      // 尝试初始化 IndexedDB
      await indexedStore.init();
      this.isIndexedDBAvailable = true;
      return true;
    } catch (error) {
      console.warn('IndexedDB not available, falling back to localStorage:', error);
      this.isIndexedDBAvailable = false;
      return false;
    }
  }

  /**
   * 获取指定类型的存储实例
   * @param {string} type 存储类型
   * @returns {BaseStore} 存储实例
   */
  getStore(type = this.defaultType) {
    if (!this.stores[type]) {
      console.warn(`Storage type "${type}" not found, using default type "${this.defaultType}"`);
      return this.stores[this.defaultType];
    }
    return this.stores[type];
  }

  /**
   * 获取可用的存储实例（自动降级）
   * @param {string} preferredType 首选存储类型
   * @returns {Promise<BaseStore>} 存储实例
   */
  async getAvailableStore(preferredType = this.defaultType) {
    // 如果首选类型是 IndexedDB，检查可用性
    if (preferredType === STORAGE_TYPES.INDEXED) {
      const isAvailable = await this.checkIndexedDBAvailability();
      if (!isAvailable) {
        console.warn('IndexedDB not available, using fallback storage');
        return this.stores[this.fallbackType];
      }
    }
    
    return this.getStore(preferredType);
  }

  /**
   * 设置默认存储类型
   * @param {string} type 存储类型
   */
  setDefaultType(type) {
    if (this.stores[type]) {
      this.defaultType = type;
    } else {
      console.warn(`Invalid storage type: ${type}`);
    }
  }

  /**
   * 创建自定义存储实例
   * @param {string} type 存储类型
   * @param {string} prefix 前缀
   * @returns {BaseStore} 存储实例
   */
  createStore(type, prefix) {
    switch (type) {
      case STORAGE_TYPES.INDEXED:
        return new IndexedStore(`${prefix}DB`, 1, `${prefix}Store`);
      case STORAGE_TYPES.LOCAL:
        return new LocalStore(prefix);
      case STORAGE_TYPES.SESSION:
        return new SessionStore(prefix);
      case STORAGE_TYPES.MEMORY:
        return new MemoryStore(prefix);
      default:
        throw new Error(`Unsupported storage type: ${type}`);
    }
  }

  /**
   * 设置值（异步，自动选择存储类型）
   * @param {string} key 键名
   * @param {any} value 值
   * @param {Object} options 选项
   * @param {string} options.type 存储类型
   * @param {number} options.expires 过期时间（毫秒）
   * @param {boolean} options.sync 是否同步到其他存储
   * @returns {Promise<boolean>}
   */
  async set(key, value, options = {}) {
    try {
      const store = await this.getAvailableStore(options.type);
      
      let result;
      if (store === indexedStore) {
        result = await store.set(key, value, options);
      } else {
        result = store.set(key, value, options);
      }

      // 如果启用同步且主存储成功，同步到备用存储
      if (result && options.sync && store === indexedStore) {
        try {
          this.stores[this.fallbackType].set(key, value, options);
        } catch (syncError) {
          console.warn('Failed to sync to fallback storage:', syncError);
        }
      }

      return result;
    } catch (error) {
      console.error('StoreManager.set error:', error);
      return false;
    }
  }

  /**
   * 获取值（异步，自动选择存储类型）
   * @param {string} key 键名
   * @param {any} defaultValue 默认值
   * @param {Object} options 选项
   * @param {string} options.type 存储类型
   * @param {boolean} options.fallback 是否启用备用存储查找
   * @returns {Promise<any>}
   */
  async get(key, defaultValue = null, options = {}) {
    try {
      const store = await this.getAvailableStore(options.type);
      
      let result;
      if (store === indexedStore) {
        result = await store.get(key, defaultValue);
      } else {
        result = store.get(key, defaultValue);
      }

      // 如果主存储没有找到且启用备用查找
      if (result === defaultValue && options.fallback && store === indexedStore) {
        try {
          const fallbackResult = this.stores[this.fallbackType].get(key, defaultValue);
          if (fallbackResult !== defaultValue) {
            // 找到数据，同步回主存储
            await this.set(key, fallbackResult, { type: STORAGE_TYPES.INDEXED });
            return fallbackResult;
          }
        } catch (fallbackError) {
          console.warn('Failed to get from fallback storage:', fallbackError);
        }
      }

      return result;
    } catch (error) {
      console.error('StoreManager.get error:', error);
      return defaultValue;
    }
  }

  /**
   * 删除值（异步）
   * @param {string} key 键名
   * @param {Object} options 选项
   * @param {string} options.type 存储类型
   * @param {boolean} options.sync 是否同步删除其他存储
   * @returns {Promise<boolean>}
   */
  async remove(key, options = {}) {
    try {
      const store = await this.getAvailableStore(options.type);
      
      let result;
      if (store === indexedStore) {
        result = await store.remove(key);
      } else {
        result = store.remove(key);
      }

      // 如果启用同步，从所有存储中删除
      if (options.sync) {
        Object.values(this.stores).forEach(s => {
          if (s !== store) {
            try {
              if (s === indexedStore) {
                s.remove(key).catch(console.error);
              } else {
                s.remove(key);
              }
            } catch (syncError) {
              console.warn('Failed to sync remove:', syncError);
            }
          }
        });
      }

      return result;
    } catch (error) {
      console.error('StoreManager.remove error:', error);
      return false;
    }
  }

  /**
   * 检查键是否存在（异步）
   * @param {string} key 键名
   * @param {Object} options 选项
   * @param {string} options.type 存储类型
   * @returns {Promise<boolean>}
   */
  async has(key, options = {}) {
    try {
      const store = await this.getAvailableStore(options.type);
      
      if (store === indexedStore) {
        return await store.has(key);
      } else {
        return store.has(key);
      }
    } catch (error) {
      console.error('StoreManager.has error:', error);
      return false;
    }
  }

  /**
   * 清空指定类型的存储（异步）
   * @param {string} type 存储类型，如果不指定则清空所有类型
   * @returns {Promise<boolean>}
   */
  async clear(type = null) {
    try {
      if (type) {
        const store = await this.getAvailableStore(type);
        if (store === indexedStore) {
          return await store.clear();
        } else {
          return store.clear();
        }
      } else {
        // 清空所有存储
        const promises = Object.entries(this.stores).map(async ([storageType, store]) => {
          try {
            if (store === indexedStore) {
              return await store.clear();
            } else {
              return store.clear();
            }
          } catch (error) {
            console.error(`Failed to clear ${storageType}:`, error);
            return false;
          }
        });
        
        const results = await Promise.all(promises);
        return results.every(result => result === true);
      }
    } catch (error) {
      console.error('StoreManager.clear error:', error);
      return false;
    }
  }

  /**
   * 智能存储：根据数据特性自动选择存储类型（异步）
   * @param {string} key 键名
   * @param {any} value 值
   * @param {Object} options 选项
   * @param {boolean} options.persistent 是否需要持久化
   * @param {boolean} options.session 是否只在会话期间有效
   * @param {number} options.expires 过期时间（毫秒）
   * @param {boolean} options.large 是否为大数据
   * @returns {Promise<boolean>}
   */
  async smartSet(key, value, options = {}) {
    let storageType;
    
    // 根据数据特性选择存储类型
    if (options.expires && options.expires < 60000) { // 小于1分钟，使用内存存储
      storageType = STORAGE_TYPES.MEMORY;
    } else if (options.session) { // 会话数据
      storageType = STORAGE_TYPES.SESSION;
    } else if (options.large || (options.persistent !== false)) { // 大数据或需要持久化
      storageType = STORAGE_TYPES.INDEXED;
    } else {
      storageType = STORAGE_TYPES.LOCAL;
    }
    
    return await this.set(key, value, { ...options, type: storageType });
  }

  /**
   * 智能获取：从多个存储类型中查找数据（异步）
   * @param {string} key 键名
   * @param {any} defaultValue 默认值
   * @param {Array<string>} searchOrder 搜索顺序
   * @returns {Promise<any>}
   */
  async smartGet(key, defaultValue = null, searchOrder = [STORAGE_TYPES.MEMORY, STORAGE_TYPES.INDEXED, STORAGE_TYPES.SESSION, STORAGE_TYPES.LOCAL]) {
    for (const type of searchOrder) {
      try {
        const result = await this.get(key, null, { type });
        if (result !== null) {
          return result;
        }
      } catch (error) {
        console.warn(`Failed to get from ${type}:`, error);
      }
    }
    return defaultValue;
  }
}

// 创建默认实例
const storeManager = new StoreManager();

// 导出默认实例和类
export default storeManager;
export { StoreManager };

// 导出各个存储实例，方便直接使用
export { indexedStore, localStore, sessStore, memStore };

// 导出存储类，方便创建自定义实例
export { IndexedStore, LocalStore, SessionStore, MemoryStore, BaseStore };

// 便捷方法对象
export const storage = {
  // 各类型存储实例
  indexed: indexedStore,
  local: localStore,
  session: sessStore,
  memory: memStore,
  
  // 管理器
  manager: storeManager,
  
  // 异步快捷方法
  set: async (key, value, options) => await storeManager.set(key, value, options),
  get: async (key, defaultValue, options) => await storeManager.get(key, defaultValue, options),
  remove: async (key, options) => await storeManager.remove(key, options),
  has: async (key, options) => await storeManager.has(key, options),
  clear: async (type) => await storeManager.clear(type),
  
  // 智能存储方法
  smartSet: async (key, value, options) => await storeManager.smartSet(key, value, options),
  smartGet: async (key, defaultValue, searchOrder) => await storeManager.smartGet(key, defaultValue, searchOrder)
};